
/* Prestado por el grupo de
 * Abramowicz
 * Goni
 * Pan
 */

#include "../include/grubInfo.h"

#define MB  1024*1024
#define CHECK_FLAG(flags,bit)   ((flags) & (1 << (bit)))

static infoGrub *info;

int
getBlockMem (void **m_address, int *m_size) {
    int addr, size = 0;
    mmapT *mmap = 0x0;

    //Si la informacion esta disponible
    if (CHECK_FLAG (info->flags, 6)) {
        for (mmap = (mmapT *) info->mmap_addr;
             (mmap + sizeof (mmap->size)) <
             (info->mmap_addr + info->mmap_length);
             mmap =
             (mmapT *) ((unsigned long) mmap + mmap->size +
                        sizeof (mmap->size)))
            //Recorro los bloques de memoria para obtener el bloque mas grande 
            if (size < mmap->length_low
                && mmap->length_low < MAX_SIZE_BLOCK_MEM) {
                addr = mmap->base_addr_low;
                size = mmap->length_low;
            }
        //Si el addr empieza en 1MB hay que correrlo por que va a pisar al kernel
        if (addr == 0x100000) {
            //Lo muevo 1MB
            addr += 1 * MB;
            //Resto el MB a la memoria
            size -= 1 * MB;
        }

        *(char **) m_address = (char *) addr;
        *m_size = size;

        return 1;
    }

    return 0;
}

int
getMemSize (void) {
    return (CHECK_FLAG (info->flags, 0)) ? info->mem_upper : 0;
}

void
set_multiBoot (unsigned long infoStruct) {
    //Seteo la variable global con la direccion
    info = (infoGrub *) infoStruct;

    return;
}
